﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using VsxFactory.Modeling.VisualStudio;

namespace VsxFactory.Modeling.Strategies.VisualStudio
{
    abstract class VSContainer 
    {
        protected HierarchyNode node;

        public VSContainer(IVsSolution solution, HierarchyNode node = null)
        {
            System.Diagnostics.Contracts.Contract.Requires(solution != null);
            this.Solution = solution;
            this.node = node;
        }

        [System.Diagnostics.Contracts.ContractInvariantMethod]
        void InvariantValidationMethod()
        {
            System.Diagnostics.Contracts.Contract.Requires(Solution != null);
        }

        public IVsSolution Solution
        {
            get; private set;
        }

        public object ExternalObject
        {
            get { return node; }
        }

        public IEnumerable<IVsProjectItem> AllElements
        {
            get
            {
                if (node == null)
                    yield break;
                foreach (var n in node.AllElements.Select(e => ((VSSolution)Solution).Cast(e)).Where(e => e != null))
                    yield return n;
            }
        }

        public T Find<T>(Func<T, bool> func) where T : class, IVsProjectItem
        {
            foreach (IVsProjectItem el in AllElements)
            {
                var item = el as T;
                if (item != null && func(item))
                    return item;
            }
            return null;
        }

        public virtual T FindByPath<T>(string fullName) where T : class, IVsProjectItem
        {
            System.Diagnostics.Contracts.Contract.Requires(!String.IsNullOrWhiteSpace(fullName));
            if (node == null)
                return null;
            var result = node.AllElements.Where(n => n.Path != null && Utils.IsSamePath(fullName, n.Path)).FirstOrDefault();
            return result != null ? ((VSSolution)Solution).Cast(result) as T : null;
        }
    }
}
